/*
 * Copyright (C) 2012-2016 TeraCN
 * 
 * This file is part of TeraCN.
 * 
 * TeraCN is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * TeraCN is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package tera.gameserver.network.serverpackets;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import tera.gameserver.model.equipment.Equipment;
import tera.gameserver.model.equipment.SlotType;
import tera.gameserver.model.playable.Player;
import tera.gameserver.network.ServerPacketType;

/**
 * @author Ronn Mod Evestu
 */
public class S_User_External_Change extends ServerPacket
{
	private static final ServerPacket instance = new S_User_External_Change();
	
	/**
	 * Method getInstance.
	 * @param player Player
	 * @return S_User_External_Change
	 */
	public static S_User_External_Change getInstance(Player player)
	{
		final S_User_External_Change packet = (S_User_External_Change) instance.newInstance();
		final ByteBuffer buffer = packet.getPrepare();
		
		try
		{
			final Equipment equipment = player.getEquipment();
			packet.writeInt(buffer, player.getObjectId());
			packet.writeInt(buffer, player.getSubId());
			equipment.lock();
			
			try
			{
				final int count = SlotType.SIZE;
				
				for (int i = 0; i < count; ++i)
				{
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_WEAPON));
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_ARMOR));
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_BOOTS));
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_GLOVES));
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_MASK));
					packet.writeInt(buffer, equipment.getItemId(SlotType.SLOT_HAT));
				}
			}
			
			finally
			{
				equipment.unlock();
			}
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeInt(buffer, 0);
			packet.writeByte(buffer, 1);
			return packet;
		}
		
		finally
		{
			buffer.flip();
		}
	}
	
	private final ByteBuffer prepare;
	
	public S_User_External_Change()
	{
		prepare = ByteBuffer.allocate(4096).order(ByteOrder.LITTLE_ENDIAN);
	}
	
	/**
	 * Method finalyze.
	 * @see rlib.util.pools.Foldable#finalyze()
	 */
	@Override
	public void finalyze()
	{
		prepare.clear();
	}
	
	/**
	 * Method getPacketType.
	 * @return ServerPacketType
	 */
	@Override
	public ServerPacketType getPacketType()
	{
		return ServerPacketType.S_USER_EXTERNAL_CHANGE;
	}
	
	/**
	 * Method isSynchronized.
	 * @return boolean
	 * @see rlib.network.packets.SendablePacket#isSynchronized()
	 */
	@Override
	public boolean isSynchronized()
	{
		return false;
	}
	
	/**
	 * Method writeImpl.
	 * @param buffer ByteBuffer
	 */
	@Override
	protected void writeImpl(ByteBuffer buffer)
	{
		writeOpcode(buffer);
		final ByteBuffer prepare = getPrepare();
		buffer.put(prepare.array(), 0, prepare.limit());
	}
	
	/**
	 * Method getPrepare.
	 * @return ByteBuffer
	 */
	public ByteBuffer getPrepare()
	{
		return prepare;
	}
}